<!--  -->

<style lang='scss' type='stylesheet/scss' scoped>
.file-item {
  cursor: pointer;
  display: flex;
  padding: 0 30px;
  box-sizing: border-box;
  text-align: center;
  height: 80px;
  line-height: 1.5;
  align-items: center;
  &.box {
    vertical-align: top;
    flex: 1;
    position: relative;
    flex-direction: column;
    padding: 10px 10px;
    .file-update-time,
    .file-size {
      display: none;
    }
    .el-icon-success {
      position: absolute;
      top: 10px;
      left: 10px;
    }
    .file-name {
      margin-top: 10px;
      text-align: center;
      .name-text {
        width: 96px;
      }
    }
    .file-picture {
      flex: 0 0 96px;
      width: 96px;
      height: 96px;
      background-size: contain;
      background-repeat: no-repeat;
      background-position: center;
    }
    height: 150px;
    margin: 8px;
  }
  &.row {
    &:nth-child(2n-1) {
      background: hsla(0, 0%, 82%, 0.18);
    }
  }
  &.checked {
    background: rgba(51, 173, 51, 0.18) !important;
  }

  &:hover {
    background: rgba(51, 173, 51, 0.18) !important;
  }
  .success,
  .el-icon-success {
    flex: 0 0 40px;
    font-size: 16px;
    color: rgb(55, 160, 55);
  }
  .file-icon {
    font-size: 16px;
    flex: 0 0 30px;
    width: 30px;
    height: 30px;
    margin: 0 10px;
    .icon {
      width: 30px;
      display: inline-block;
    }
  }
  .file-name {
    text-align: left;
    flex: 1;
    font-size: 12px;
    display: inline-block;
    width: 100%;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    .name-text {
      overflow: hidden;
      white-space: nowrap;
      text-overflow: ellipsis;
      display: inline-block;
      padding: 0 5px;
      &:hover {
        text-decoration: underline;
      }
    }
  }
  .file-size {
    flex: 0 0 150px;
    width: 150px;
    font-size: 12px;
    color: #797979;
  }
  .file-update-time {
    flex: 0 0 180px;
    width: 180px;
    font-size: 12px;
    color: #797979;
  }
}

.file-list-warpper {
  position: relative;
  min-height: calc(100vh - 40px - 48px - 48px - 48px - 10px);
  &.box-warpper {
    width: 100%;
    display: flex;
    flex-wrap: wrap;
    padding: 12px;
    box-sizing: border-box;
    align-content: flex-start;

    font-size: 0;
  }
}

.hammer-mask {
  position: absolute;
  top: 0;
  left: 0;
  width: 100px;
  height: 100px;
  border: dashed 1px black;
  background: rgba(113, 113, 113, 0.28);
  transform-origin: left top;
}
</style>

<template>
  <div>
    <v-contextmenu ref="contextmenu"
                   theme="dark">
      <v-contextmenu-item v-if="checkFiles.length===1"
                          @click.native="rename">重命名</v-contextmenu-item>
      <v-contextmenu-item :divider="true"></v-contextmenu-item>
      <v-contextmenu-item @click.native="copyTo">拷贝到</v-contextmenu-item>
      <v-contextmenu-item @click.native="moveTo">移动到</v-contextmenu-item>
      <v-contextmenu-item :divider="true"></v-contextmenu-item>
      <v-contextmenu-item @click.native="deleteFiles">删除</v-contextmenu-item>
    </v-contextmenu>
    <div class="file-list-warpper"
         :class="isRow?'row-warpper':'box-warpper'"
         @click="clearFiles"
         v-hammer:pan='pan'
         v-hammer:panstart='panStart'
         v-hammer:panend='panEnd'>
      <div class="file-item"
           :class="isRow?'row':'box'"
           v-if="addFolderInputVisible">
        <i class="el-icon-success"
           style="opacity:0"></i>
        <div class="file-icon"
             v-if="isRow">
          <img src="../../assets/icons/folder.png"
               class="icon">
        </div>
        <div class="file-picture"
             v-if="!isRow"
             :style="`background-image:url(${require('../../assets/icons/folder-box.png')})`"></div>
        <input type="text"
               class="file-name"
               ref="addInput"
               @keydown.enter="blurInput"
               @blur="addInputBlur"
               v-model="addFolderName">
        <div class="file-size"></div>
        <div class="file-update-time"></div>
      </div>
      <div class="file-item"
           @contextmenu.prevent.stop="rightClick(fileItem)"
           v-contextmenu:contextmenu
           :id="fileItem.id"
           ref="fileItems"
           :class="`${checkFiles.includes(fileItem.id)?'checked':''} ${isRow?'row':'box'}`"
           @click.stop="clickItem(fileItem)"
           v-for="fileItem in fileList">
        <i class="el-icon-success"
           :style="`opacity:${checkFiles.includes(fileItem.id)?'1':'0'}`"></i>
        <div class="file-icon"
             v-if="isRow">
          <img :src="require(`../../assets/icons/${fileItem.isFolder?'folder':fileItem.type.split('/')[0]}.png`)"
               class="icon">
        </div>
        <div class="file-picture"
             v-if="!isRow"
             :style="`background-image:url(${fileItem.isFolder?require('../../assets/icons/folder-box.png'):$host+fileItem.path})`"></div>
        <div class="file-name">
          <input type="text"
                 v-if="renameVisible&&checkFiles.includes(+fileItem.id)"
                 class="name-text"
                 ref="nameInput"
                 style="outline:none"
                 :style="!isRow?'text-align:center;':''"
                 @keydown.esc="cancelRename"
                 @keydown.enter="blurRenameInput"
                 @blur="renameFile(fileItem)"
                 v-model="addFolderName">
          <span class="name-text"
                v-else
                @click.stop="clickFile(fileItem)">{{fileItem.name}}</span>
        </div>
        <div class="file-size">{{fileItem.size|parseSize}}</div>
        <div class="file-update-time">{{fileItem.updatedAt|parseTime("{y}-{m}-{d} {h}:{i}:{s}")}}</div>
      </div>

      <div class="file-item box"
           v-if="!isRow"
           style="height:0;opacity:0;cursor:auto"
           v-for="fileItem in 10">
        <div class="file-picture"
             style="height:0;flex:0 0 0 "></div>
        <div class="file-name"
             style="height:0">
          <span class="name-text"
                style="height:0">NAME</span>
        </div>
      </div>

      <div class="hammer-mask"
           :style="`
         top:${startPoint.y-48-40-48-48}px;
         left:${startPoint.x-10}px;
         width:${Math.abs(maskBox.width)}px;
         height:${Math.abs(maskBox.height)}px;
         transform:scale(${maskBox.width<0?'-1':'1'},${maskBox.height<0?'-1':'1'})
         `"></div>
    </div>
  </div>
</template>

<script type='text/ecmascript-6'>
import { mapGetters } from "vuex";
export default {
  props: ["file"],
  filters: {
    parseSize(size) {
      if (!size) {
        return "-";
      }

      const S = 1024;

      if (size < S) {
        return size + "B";
      }

      if (size < S * S) {
        return Math.ceil(size / S) + "KB";
      }

      if (size < S * S * S) {
        return Math.ceil(size / S / S) + "MB";
      }

      if (size < S * S * S * S) {
        return Math.ceil(size / S / S / S) + "GB";
      }
    }
  },
  computed: {
    ...mapGetters(["fileList", "checkFiles", "isRow"])
  },
  watch: {
    fileList(newVal) {
      console.log(newVal);
    }
  },
  data() {
    return {
      mousePan: false,
      // 新建文件输入框可见
      addFolderInputVisible: false,
      // 新建文件名称
      addFolderName: "",

      startPoint: {
        x: 0,
        y: 0
      },
      maskBox: {
        width: 0,
        height: 0
      },
      renameVisible: false
    };
  },
  methods: {
    moveTo() {
      this.$emit("moveTo");
    },
    copyTo() {
      this.$emit("copyTo");
    },
    // 右键
    rightClick(item) {
      if (!this.checkFiles.includes(item.id)) {
        this.clearFiles();
        this.clickItem(item);
      }
    },
    // 删除
    async deleteFiles() {
      await this.$store.dispatch("file/deleteFileList", this.checkFiles);

      this.$notify.success({
        title: "成功",
        message: "成功"
      });
    },
    cancelRename() {
      this.addFolderName = "";
      this.$refs.nameInput[0].blur();
    },
    // 取消 focus
    blurRenameInput() {
      this.$refs.nameInput[0].blur();
    },
    // 重命名输入框focus
    rename() {
      this.renameVisible = true;
      this.$nextTick(_ => {
        this.$refs.nameInput[0].focus();
      });
    },
    clearFiles() {
      if (!this.mousePan) {
        this.$store.commit("file/CLEAR_FILES");
      }
    },
    pan(e) {
      let scroll = document.querySelector(
        "#file-list-scroll .el-scrollbar__wrap"
      );

      let ids = [];
      for (let index = 0; index < this.$refs.fileItems.length; index++) {
        const element = this.$refs.fileItems[index];

        let rect = element.getBoundingClientRect();

        let mask = {
          left:
            this.startPoint.x > this.startPoint.x + this.maskBox.width
              ? this.startPoint.x + this.maskBox.width
              : this.startPoint.x,
          right:
            this.startPoint.x > this.startPoint.x + this.maskBox.width
              ? this.startPoint.x
              : this.startPoint.x + this.maskBox.width,
          top:
            this.startPoint.y > this.startPoint.y + this.maskBox.height
              ? this.startPoint.y + this.maskBox.height
              : this.startPoint.y,
          bottom:
            this.startPoint.y > this.startPoint.y + this.maskBox.height
              ? this.startPoint.y
              : this.startPoint.y + this.maskBox.height
        };

        if (
          !(
            (mask.left < rect.left && mask.right < rect.left) ||
            (mask.right > rect.right && mask.left > rect.right) ||
            (mask.top - scroll.scrollTop < rect.top &&
              mask.bottom - scroll.scrollTop < rect.top) ||
            (mask.bottom - scroll.scrollTop > rect.bottom &&
              mask.top - scroll.scrollTop > rect.bottom)
          )
        ) {
          ids.push(element.id);
        }
      }
      this.$store.dispatch("file/checkFiles", ids);
      this.maskBox = {
        width: e.center.x - this.startPoint.x,
        height: e.center.y - this.startPoint.y + scroll.scrollTop
      };

      let view = document.querySelector(
        "#file-list-scroll .el-scrollbar__wrap .el-scrollbar__view"
      );

      let viewRect = view.getClientRects()[0];
      let scrollRect = scroll.getClientRects()[0];

      if (e.center.y < 240 && scroll.scrollTop > 0) {
        scroll.scrollTop -= 8;
      } else if (
        e.center.y > document.body.clientHeight - 60 &&
        viewRect.height > scrollRect.height + scroll.scrollTop
      ) {
        scroll.scrollTop += 8;
      }
    },
    panStart(e) {
      this.mousePan = true;
      let scroll = document.querySelector(
        "#file-list-scroll .el-scrollbar__wrap"
      );
      this.startPoint = { x: e.center.x, y: e.center.y + scroll.scrollTop };
    },
    panEnd() {
      setTimeout(() => {
        this.mousePan = false;
      }, 100);
      this.startPoint = { x: 0, y: 0 };
      this.maskBox = {
        width: 0,
        height: 0
      };
    },
    clickItem(file) {
      if (this.checkFiles.includes(file.id)) {
        this.$store.dispatch("file/uncheckOneFile", file.id);
      } else {
        this.$store.dispatch("file/checkOneFile", file.id);
      }
    },
    // 重命名提交
    async renameFile(item) {
      let addFolderName = this.addFolderName.trim();
      if (addFolderName) {
        await this.$store.dispatch("file/renameFile", {
          id: item.id,
          name: addFolderName
        });
        this.addFolderName = "";
      }
      this.renameVisible = false;
    },
    // 新增文件夹
    async addInputBlur() {
      let addFolderName = this.addFolderName.trim();
      if (addFolderName) {
        this.$store.dispatch("file/addFolder", addFolderName);
        this.addFolderName = "";
      }
      this.addFolderInputVisible = false;
    },
    blurInput() {
      this.$refs.addInput.blur();
    },
    addFolder() {
      this.addFolderInputVisible = true;

      this.$nextTick(_ => {
        this.$refs.addInput.focus();
      });
    },
    // 点击文件名称
    clickFile(file) {
      if (file.isFolder) {
        this.$store.dispatch("file/clickFolder", file);
      } else {
        this.$emit("update:file", file);
      }
    }
  }
};
</script>
